package com.ztf.ai.ticket;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

@Service
public class TicketInventoryMonitorService {
    private final RedisTemplate<String, Object> redisTemplate;
    private final TicketOrderService ticketOrderService;
    private final ThreadPoolTaskExecutor asyncExecutor; // 异步执行器，避免定时任务阻塞

    // 注入依赖
    public TicketInventoryMonitorService(
            RedisTemplate<String, Object> redisTemplate,
            TicketOrderService ticketOrderService,
            ThreadPoolTaskExecutor asyncExecutor
    ) {
        this.redisTemplate = redisTemplate;
        this.ticketOrderService = ticketOrderService;
        this.asyncExecutor = asyncExecutor;
    }

    /**
     * 定时查询所有未完成的抢票任务（每2秒执行一次，对应application.yml中的配置）
     */
    // @Scheduled(fixedDelayString = "${ticket.query.interval}")
    public void monitorAllTasks() {
        // 1. 从Redis中获取所有“待监控”的任务（key前缀：TICKET_TASK_）
        String taskKeyPattern = "TICKET_TASK_TASK_*";
        redisTemplate.keys(taskKeyPattern).forEach(taskKey -> {
            TicketTaskDTO taskDTO = (TicketTaskDTO) redisTemplate.opsForValue().get(taskKey);
            if (taskDTO != null && "PENDING".equals(getTaskStatus(taskDTO.getTaskId()))) {
                // 2. 异步查询余票，避免单任务阻塞整个监控流程
                asyncExecutor.execute(() -> queryTicketInventory(taskDTO));
            }
        });
    }

    /**
     * 调用票务接口查询余票
     */
    private void queryTicketInventory(TicketTaskDTO taskDTO) {
        // 模拟调用12306合规接口（实际需替换为真实接口调用逻辑）
        Mono<TicketInventoryDTO> inventoryMono = callTicketApi(taskDTO);
        // 3. 处理查询结果：有票则触发下单，无票则更新监控状态
        inventoryMono.subscribe(inventory -> {
            if (inventory.isHasTicket()) {
                // 发现余票，触发自动下单
                ticketOrderService.submitOrder(taskDTO, inventory, 1);
                // 更新任务状态为“已触发下单”
                updateTaskStatus(taskDTO.getTaskId(), "ORDERING");
            } else {
                // 无票，更新监控日志
                updateTaskLog(taskDTO.getTaskId(), "当前无余票，继续监控");
            }
        }, error -> {
            // 接口调用失败（如限流），记录异常并降低查询频率（暂略）
            updateTaskLog(taskDTO.getTaskId(), "余票查询失败：" + error.getMessage());
        });
    }

    // 模拟票务接口调用（实际需对接官方或合规第三方接口）
    private Mono<TicketInventoryDTO> callTicketApi(TicketTaskDTO taskDTO) {
        return Mono.just(new TicketInventoryDTO() {{
            setTrainNo(taskDTO.getTrainNo());
            setHasTicket(true); // 模拟有票场景，实际需根据接口返回判断
            setSeatType(taskDTO.getSeatType());
            setTicketCount("1-5张");
        }});
    }

    // 辅助方法：获取任务状态（Redis存储）
    private String getTaskStatus(String taskId) {
        return (String) redisTemplate.opsForValue().get("TICKET_TASK_STATUS_" + taskId);
    }

    // 辅助方法：更新任务状态
    private void updateTaskStatus(String taskId, String status) {
        redisTemplate.opsForValue().set("TICKET_TASK_STATUS_" + taskId, status);
    }

    // 辅助方法：更新任务日志
    private void updateTaskLog(String taskId, String log) {
        redisTemplate.opsForList().rightPush("TICKET_TASK_LOG_" + taskId, log);
    }
}